// 足球奖金评测 定胆评测逻辑抽取
import MyUtils from './calc'
import { difference, orderBy } from 'lodash-es'
import { myCalc, arral, arrcl, GetVotetype, MaxJiangjin, BJBetWagerCount, ComputeCombineNum } from './counterFun'

export const wfs = {
    'had': '0',
    'hhad': '1',
    'crs': '2',
    'ttg': '4',
    'hafu': '3'
}
const wfconf = {
    0: 'spf',
    1: 'rqspf',
    2: 'bf',
    3: 'bqc',
    4: 'zjq'
}

function sortByMaxDescending(matchChoose) {
    const json = JSON.parse(JSON.stringify(matchChoose))
    const entries = Object.entries(json)
    const entriesSort = entries.sort((a, b) => b[1].max - a[1].max)
    const resary = entriesSort.map((el) => {
        return { [el[0]]: el[1] }
    })
    return resary
}
function getMinMaxOddsFilter1(matchChoose, choose) {
    // 记录每场比赛中最大赔率[每场比赛选择玩法中最大的]
    const maxfilter = []
    // 先将每场比赛中最大赔率降序排列
    const matchChooseSort = sortByMaxDescending(matchChoose)
    // 筛选出最大/最小具体的玩法信息，用于从串关组合中筛选出注数
    for (let i = 0; i < matchChooseSort.length; i++) {
        Object.entries(matchChooseSort[i]).forEach(([key, val]) => {
            const arr = Object.values(val.aMax);
            const ary = arr.filter(v => v > 0)
            // ary.length aMax内的有效值的个数, arr.length本厂比赛的所有玩法个数
            maxfilter.push(`${key}=${val.max}=${ary.length}=${arr.length}`)
        })
    }
    // 记录每场比赛中最小赔率[每场比赛只选取所有玩法中最小的]
    let minfilter = []
    Object.entries(choose).forEach(([key, val]) => {
        const keymatchchoose = matchChoose[key]
        let mintxt = ''
        let min = keymatchchoose.min
        for (const key1 in val) {
            for (const key2 in val[key1]) {
                const el = val[key1][key2]
                if (el.sp <= min) {
                    min = el.sp
                    mintxt = `${key}=${el.sp}=1=${Object.keys(keymatchchoose.aMax).length}`
                }
            }
        }
        minfilter.push(mintxt)
    })
    // 最小赔率最终值升序排列
    minfilter = minfilter.sort((a, b) => {
        const ael = a.split('=')
        const bel = b.split('=')
        return Number(ael[1]) - Number(bel[1])
    })

    return { maxfilter, minfilter }
}
function computedMaxOrMinBouns(filterData, str, chuan, choose_len, multiNum) {
    const combineObj = {}
    for (const key in filterData) {
        const element = filterData[key] // 命中几场的比赛组合 4 3 2
        combineObj[key] = {}
        // 先获取用户选择的过关方式
        let bouns = 0
        let MaxLen = 0
        for (let gg of chuan) {
            const c = Number(gg.split('_')[0])
            if (choose_len > 15 && ComputeCombineNum(element.length, c) > 100000) {
                continue;
            }
            const ggary = GetVotetype(gg).split(' ') // ['2', '3']
            const isMcn = !gg.includes('_1')
            for (let takeNum of ggary) {
                const tn = Number(takeNum);
                // 如果选择M串N的多串方式，转化后的串关小于比赛场数需要补当前组合存在的次数
                const evt = (isMcn && tn < choose_len);
                const erArr = MyUtils.getNumbers(element, tn, false) // 二维数组，所有的组合
                // 计算最大值或者最小值
                if (combineObj[key][gg]) {
                    combineObj[key][gg] = combineObj[key][gg].concat(erArr)
                } else {
                    combineObj[key][gg] = erArr;
                }
                let sum = 0;
                for (let item of erArr) {
                    const balanceItem = difference(filterData[choose_len], item)
                    const len = evt && balanceItem.length > 0 ? balanceItem.reduce((prev, current) => prev + Number(current.split('=')[3]), 0) : 1;
                    let mult = 1
                    let multN = 1
                    for (let sele of item) {
                        const els = sele.split('=')
                        const ssp = els[1] // 赔率
                        const nnm = els[2] // 个数
                        mult *= Number(ssp)
                        multN *= Number(nnm)
                    }
                    const limit = MaxJiangjin[tn] * multN; // 限额
                    sum += (mult > limit ? limit : mult) * len;
                }
                MaxLen += erArr.length;
                bouns += sum;
            }
        }
        combineObj[key][`${str}Bouns`] = bouns * 2 * multiNum; // 奖金
        combineObj[key]['notenum'] = MaxLen;
    }
    return combineObj;
}
// 计算不存在胆码情况下的奖金评测信息计算
function getMinMaxPrize1(chuan, selChuanArr, matchChoose, choose, choose_len, multiNum, onlyMax = false) {
    if (onlyMax){
        // 只计算最大奖金
        const { maxfilter } = getMinMaxOddsFilter1(matchChoose, choose)
        const oddsMaxFilterKeyStr = {
            [choose_len]: [...maxfilter.slice(0, choose_len)]
        }
        // oddsMaxFilterKeyStr[choose_len] = [...maxfilter.slice(0, choose_len)]
        const maxObj = computedMaxOrMinBouns(oddsMaxFilterKeyStr, 'max', chuan, choose_len, multiNum);
        return maxObj[choose_len].maxBouns.toFixed(2);
    }else{
        // 计算已选择的串关方式中的最小值
        let __min = selChuanArr[0]
        // 得到自定义比赛选择玩法中所有赔率最大/最小值排序后
        const { maxfilter, minfilter } = getMinMaxOddsFilter1(matchChoose, choose)
        // 拼凑用于计算奖金评测信息的最大/最小结构
        const oddsMinFilterKeyStr = {}
        const oddsMaxFilterKeyStr = {}
        for (let i = __min; i <= choose_len; i++) {
            // 最小奖金数据拼接
            oddsMinFilterKeyStr[i] = [...minfilter.slice(0, i)]
            // 最大奖金数据拼接
            oddsMaxFilterKeyStr[i] = [...maxfilter.slice(0, i)]
        }
        // console.log("🚀 ~ getMinMaxPrize1 ~ oddsMinFilterKeyStr:", oddsMinFilterKeyStr)
        // console.log("🚀 ~ getMinMaxPrize1 ~ oddsMaxFilterKeyStr:", oddsMaxFilterKeyStr)
        // 最小奖金计算
        const minObj = computedMaxOrMinBouns(oddsMinFilterKeyStr, 'min', chuan, choose_len, multiNum);
        // 最大奖金计算
        const maxObj = computedMaxOrMinBouns(oddsMaxFilterKeyStr, 'max', chuan, choose_len, multiNum);
        // 合并最大最小计算到一个奖金评测对象内
        const bounsTest = [];
        for (let key in minObj) {
            bounsTest.push({
                "hitnum": key,
                "notenum": minObj[key].notenum,
                "minBouns": minObj[key].minBouns,
                "maxBouns": maxObj[key].maxBouns,
            })
        }
        return bounsTest.sort((a, b) => Number(b.hitnum) - Number(a.hitnum))
    }
}

// 筛选组合是否符合当前的胆拖命中情况
function isKeyInTarge(key1, targetAry) {
    const sourceKeyAry = key1.split(',')
    for (let i = 0; i < sourceKeyAry.length; i++) {
        const element = sourceKeyAry[i];
        if (targetAry.indexOf(element) < 0) {
            return false
        }
    }
    return true
}
// 得到具体串关方式下的胆拖组合数据
function getDanTuoWagerList(thispl, ggWay, c, wagerDT) {
    console.log("🚀 ~ getDanTuoWagerList ~ thispl, ggWay, c:", thispl, ggWay, c)
    const voteType = GetVotetype(ggWay);
    const voteArr = voteType.split(" ");
    for (let sai = 0; sai < thispl.length; sai++) {
        const thisZuHe = thispl[sai];
        for (let v = 0; v < voteArr.length; v++) {
            const vVal = voteArr[v];
            const thisBetWagerCount = BJBetWagerCount[c][vVal];
            const thisBetWagerCountArr = thisBetWagerCount.split(",");
            for (let betV = 0; betV < thisBetWagerCountArr.length; betV++) {
                const betZuHeVal = thisBetWagerCountArr[betV];
                const betZuHeArr = betZuHeVal.split("/");
                // ----start 记录符合的组合情况 ----
                // 特殊情况ggArr[1]!=='1'，需要计算 不符合组合 数量
                // ['38.5-4-6001', '40-4-6002', '12-3-6003'] 假设从中取2的组合 ary1 = ['40-4-6002', '12-3-6003']，此时 ary1 存在的个数应该是 3('12-3-6003'因为6003中存在3中玩法)，ary1 组合的赔率计算为 40*12*3
                const _betZuHeArr = betZuHeArr.map(v => Number(v) - 1)
                const ary1 = []
                const ary2 = []
                if (thisZuHe.length === _betZuHeArr.length) {
                    ary1.push(...thisZuHe)
                } else {
                    for (let i = 0; i < thisZuHe.length; i++) {
                        if (_betZuHeArr.includes(i)) {
                            ary1.push(thisZuHe[i])
                        } else {
                            ary2.push(thisZuHe[i])
                        }
                    }
                }
                // 组合的倍数
                let mmn = 1;
                if (ary2.length) {
                    mmn = ary2.reduce((pre, cur) => pre * Number(cur.split('-')[1]), 1)
                }
                // 计算组合的奖金
                let zc = ary1.reduce((pre, cur) => pre * Number(cur.split('-')[0]), 1) * mmn
                const maxxx = MaxJiangjin[vVal];
                if (maxxx && zc > maxxx) {
                    zc = maxxx;
                }
                // 计算ary1中的胆拖情况
                const dtInfAry = ary1.map(v => v.split('-')[3])
                const _key = dtInfAry.join(',')
                // 赋值记录
                if (wagerDT[_key]) {
                    wagerDT[_key].push([ary1, zc, mmn])
                } else {
                    wagerDT[_key] = [[ary1, zc, mmn]]
                }
                // ----end----
            }
        }
    }
}
// 用于得到拼凑后的最大/最小胆拖数组情况
function getMinMaxOddsDanTuo(ty, matchChoose, choose, dans) {
    let a = [] // 拖数组
    let b = [] // 胆数组
    if (ty === 'max') {
        // 最大值计算 先将每场比赛中最大赔率降序排列
        const matchChooseSort = sortByMaxDescending(matchChoose)
        // 记录胆拖数据信息
        let ai = 0
        let bi = 0
        for (let i = 0; i < matchChooseSort.length; i++) {
            for (const mod in matchChooseSort[i]) {
                const t = matchChooseSort[i][mod];
                const len = Object.keys(t.aMax).length
                let tp = `${t.max}-${len}-${mod}`
                if (dans.includes(mod)) {
                    tp += `-d${bi}`
                    b.push([tp])
                    bi++
                } else {
                    tp += `-t${ai}`
                    a.push([tp])
                    ai++
                }
            }
        }
        console.log("🚀 ~ max ~ a, b:", a, b)
    } else if (ty === 'min') {
        let ary = []
        // 最小值计算 记录每场比赛中最小赔率[每场比赛只选取所有玩法中最小的]
        Object.entries(choose).forEach(([key, val]) => {
            const keymatchchoose = matchChoose[key]
            let min = keymatchchoose.min
            const len = Object.keys(keymatchchoose.aMax).length
            let keyary = []
            for (const key1 in val) {
                for (const key2 in val[key1]) {
                    const el = val[key1][key2]
                    if (el.sp <= min) {
                        min = el.sp
                        keyary = [el.sp, len, key, (dans.includes(key)?1:0)]
                    }
                }
            }
            ary.push(keyary)
        })
        // 排序 降序排列
        ary.sort((a, b) => a[0] - b[0])
        // 记录胆拖数据信息
        let ai = 0
        let bi = 0
        for (let ii = 0; ii < ary.length; ii++) {
            const element = ary[ii]
            if (element[3] === 1) {
                b.push([`${element[0]}-${element[1]}-${element[2]}-d${bi}`])
                bi++
            } else {
                a.push([`${element[0]}-${element[1]}-${element[2]}-t${ai}`])
                ai++
            }
        }
        console.log("🚀 ~ min ~ a, b:", a, b)
    }
    return { a, b }
}
// d为胆的length
function getDanTuoResPC(dtNumAry, mm, mmobj, dans, chuan, matchChoose, choose, multiNum) {
    const d = dans.length;
    const { a, b } = getMinMaxOddsDanTuo(mm, matchChoose, choose, dans)
    // 记录串关对应的组合情况
    let wagerDT = {}
    const macthNum = a.length + b.length;
    for (let i = 0; i < chuan.length; i++) {
        const ggWay = chuan[i];
        // myCalc方法
        const ggArr = ggWay.split('_');
        const c = Number(ggArr[0]);
        // 在现有模式下，取消了胆命中范围的限制 minabs === maxabs
        // 这里不再进行循环操作
        // for (let d = minabs; d <= maxabs; d++) {
        // if (macthNum > 15 && ComputeCombineNum(b.length, d) > 100000) { return false;}
        let sbZuHe = arrcl(b, d);
        let saZuHeVal = c - d;
        if (a.length > 0) {
            if (saZuHeVal >= 0) {
                if (macthNum > 15 && ComputeCombineNum(a.length, saZuHeVal) > 100000) {
                    // return false;
                    continue;
                }
                let saZuHe = arrcl(a, saZuHeVal);
                if (sbZuHe.length * saZuHe.length > 100000) {
                    // return false;
                    continue;
                }
                var temSbZuHe = [];
                for (var sk in sbZuHe) {
                    for (var ak in saZuHe) {
                        temSbZuHe.push(sbZuHe[sk].concat(saZuHe[ak]));
                    }
                }
                sbZuHe = temSbZuHe;
            } else {
                continue;
            }
        } else {
            if (saZuHeVal < 0) {
                sbZuHe = arrcl(b, c)
            }
        }
        for (let z = 0; z < sbZuHe.length; z++) {
            const thispl = arral(sbZuHe[z]);
            getDanTuoWagerList(thispl, ggWay, c, wagerDT)
        }
        // }
    }
    console.log('************** wagerDT', wagerDT)

    const bIndex3Ary = b.map(ar => ar.map(v => v.split('-')[3]))
    const aIndex3Ary = a.map(ar => ar.map(v => v.split('-')[3]))
    for (let ii = 0; ii < dtNumAry.length; ii++) {
        const key = dtNumAry[ii];
        // 当前命中情况
        const keyAry = key.split('_')
        // 当前命中情况中包含的 胆码个数
        const dLen = Number(keyAry[0])
        // 当前命中情况中包含的 拖码个数
        const tLen = Number(keyAry[1])
        // 计算组合中具体的 奖金 组合数组 数量
        let sum1 = 0
        let ary1 = []
        let total1 = 0
        Object.entries(wagerDT).forEach(([key1, array]) => {
            let targetAry = []
            targetAry = bIndex3Ary.slice(0, dLen).concat(aIndex3Ary.slice(0, tLen)).flat()
            if (isKeyInTarge(key1, targetAry)) {
                for (let aai = 0; aai < array.length; aai++) {
                    const element = array[aai];
                    ary1.push(element[0])
                    sum1 += element[1]
                    total1 += element[2]
                }
            }
        })

        // 从已经得到的组合中计算具体的奖金
        if (sum1 && total1) {
            if (mmobj[key]) {
                mmobj[key][`${mm}Money`] = sum1 * 2 * multiNum
            } else {
                mmobj[key] = {
                    danNum: dLen,
                    tuoNum: tLen,
                    [`${mm}Money`]: sum1 * 2 * multiNum,
                    winNum: total1
                }
            }
        }
    }
}
// 计算胆码存在下的奖金评测
function getDanMinMaxPrize(chuan, selChuanArr, matchChoose, choose, choose_len, multiNum, dans, onlyMax = false) {
    if (onlyMax) {
        // 可能的胆拖命中情况
        const d = dans.length
        const t = choose_len - d
        let __min = selChuanArr[0]
        const dtNumAry = []
        const sumdt = d + t
        const keydt = `${d}_${t}`
        // 全为胆码的组合 || 同时存在 胆码和拖码 的组合
        if (sumdt >= __min) {
            dtNumAry.push(keydt)
        }
        // 根据得到的组合情况，计算可能的评测信息
        let resMaxPC = {}
        getDanTuoResPC(dtNumAry, 'max', resMaxPC, dans, chuan, matchChoose, choose, multiNum)
        return Object.values(resMaxPC)[0].maxMoney.toFixed(2);
    } else {
        // 可能的胆拖命中情况
        const danlen = dans.length
        const tuolen = choose_len - danlen
        let __min = selChuanArr[0]
        let __minM = selChuanArr[1]
        const dtNumAry = []
        for (let d = 0; d <= danlen; d++) {
            for (let t = 0; t <= tuolen; t++) {
                const sumdt = d + t
                const keydt = `${d}_${t}`
                if (d === 0) {
                    // 只有串M方式中存在胆个数为0的情况 全为拖码的组合
                    if (__minM && t >= __minM) {
                        dtNumAry.push(keydt)
                    }
                } else {
                    // 全为胆码的组合 || 同时存在 胆码和拖码 的组合
                    if (sumdt >= __min) {
                        dtNumAry.push(keydt)
                    }
                }
            }
        }
        console.log("🚀 ~ getMinMaxPrize ~ dtNumAry:", dtNumAry)

        // 根据得到的组合情况，计算可能的评测信息
        let resMaxPC = {}
        getDanTuoResPC(dtNumAry, 'max', resMaxPC, dans, chuan, matchChoose, choose, multiNum)
        getDanTuoResPC(dtNumAry, 'min', resMaxPC, dans, chuan, matchChoose, choose, multiNum)
        return orderBy(Object.values(resMaxPC), ['danNum', 'tuoNum'], ['desc', 'desc']);
    }
}

// 足球奖金优化所需数据
function optNeedData(orderData, chuans) {
    const arr = orderData;
    let zuhe = [], possibleComb = [];
    const pmTable = { // 玩法对照表
        'had': 'shengfu', // 胜平负
        'hhad': 'rangqiu', // 让胜平负
        'crs': 'bifen', // 比分
        'ttg': 'jinqiu', // 总进球
        'hafu': 'banquanchang', // 半全场
    }
    for (const cg of chuans) { // 循环串关方式
        const chuanNums = GetVotetype(cg).split(' ')
        let combErArr = []
        for (const chuanNum of chuanNums) {
            const combErArr2 = MyUtils.getNumbers(arr, Number(chuanNum), false)
            for (const item of combErArr2) {
                combErArr = combErArr.concat(arral(item))
            }
        }
        const chuanItem = combErArr.map(comb => {
            return comb.map(select => {
                return [
                    select.home, // 队伍名称
                    select.polygoal, // 让球
                    Number(select.odds), // 赔率
                    select.result, // 所选玩法名称
                    Number(pmTable[select.type] == 'rangqiu' ? `-${select.odds}` : select.odds), // 赔率
                    pmTable[select.type], // 玩法名称拼音 从玩法对照表中取出
                    select.weekNum.charAt(0) == '0' ? ('7' + select.weekNum.slice(1)) : select.weekNum, // 比赛代码 周日是0需要转换为7
                    select.guest, // 客队名称
                    select.matchId, // 比赛ID
                    select.play,
                ];
            })
        })
        zuhe = zuhe.concat(chuanItem);
    }
    // 记录所有比赛内存在的玩法
    const pmArr = [];
    for (const match of orderData) { // 循环比赛
        const mArr = []; // 同一场比赛内的所有选择的项
        for (const item of match){
            const pm = item.type;
            const weekNum = item.weekNum.charAt(0) == '0' ? ('7' + item.weekNum.slice(1)) : item.weekNum
            if (!pmArr.includes(pm)) {
                pmArr.push(pm);
            }
            mArr.push(`${weekNum}@${pmTable[pm]}@${item.result}`);
        }
        possibleComb.push(mArr);
    }

    // 是否混合多种玩法（只要所有比赛存在不同玩法就是mixed）
    const isMixed = pmArr.length > 1; // 是否混合多种玩法
    const canHot = chuans.length == 1 && chuans[0].includes(orderData.length);// 串关只选择一种，N场比赛N串1的情况下canHot才为true
    const parame = {
        canHot,
        changshu: orderData.length, // 选择了几场比赛
        guoguan: chuans, // ['2_1','3_1']
        money: zuhe.length * 2, // totalMoney.value 包含元不适用
        type: isMixed ? 'mixed' : 'single', // single mixed
        zuhe,
    }
    return { parame, possibleComb: arral(possibleComb) };
}

// 根据玩法之间的互斥关系，计算每场比赛中选择玩法的最大赔率，
function countMaxOdds(mod, rq, mid, odds) {
    let position = getPosition(rq)
    let len = 0
    let max = null
    let min = 10000
    let max_vs = {}
    let zkn = null
    // 增加 记录最大赔率的玩法
    let max_wf = {}
    for (let i = 0; i < position.length; i++) {
        let v = 0
        let s = 0
        let vs = []
        for (let wf = 0; wf < position[i].length; wf++) {
            vs[wf] = []
            for (let k = 0; k < position[i][wf].length; k++) {
                let el = position[i][wf][k]
                let wz = wf === 1 ? (el > 0 ? 0 : (el < 0 ? 2 : 1)) : el
                if (odds[wf] && odds[wf][wz]) {
                    vs[wf].push(odds[wf][wz].sp)
                }
            }
            if (vs[wf].length > 0) {
                v += Math.max.apply(vs[wf], vs[wf])
                s += Math.min.apply(vs[wf], vs[wf])
            }
        }
        if (max === null || v > max) {
            max = v
            zkn = i
        }
        if (s && (min === null || s < min)) {
            min = s
        }
    }
    for (let wf = 0; wf < position[zkn].length; wf++) {
        for (let j = 0; j < position[zkn][wf].length; j++) {
            const el = position[zkn][wf][j]
            let wz = wf === 1 ? (el > 0 ? 0 : (el < 0 ? 2 : 1)) : el
            if (odds[wf] && odds[wf][wz] && !max_vs[wf]) {
                max_vs[wf] = odds[wf][wz].sp
                max_wf[wf] = odds[wf][wz].xx
                continue
                // return false
            }
        }
    }
    for (const key in odds) {
        len += Object.values(odds[key]).length
        if (!max_vs[key]) {
            max_vs[key] = 0
        }
    }
    return { max, min, len, mid, moder: mod, aMax: max_vs, dan: 0 };
    // matchChoose.value[mod] = { max, min, len, mid, moder: mod, aMax: max_vs, dan: 0, wfMax: max_wf }
}
function getPosition(n) {
    n = -1 * Number(n);
    let zsArr = n > 0 ? [1, 0, -1] : [1];
    let zfArr = n < 0 ? [1, 0, -1] : [-1];
    if (Math.abs(n) === 1) {
        zsArr = n > 0 ? [1, 0] : [1];
        zfArr = n < 0 ? [0, -1] : [-1];
    } else {
        zsArr = n > 0 ? [1, 0, -1] : [1];
        zfArr = n < 0 ? [1, 0, -1] : [-1];
    }
    let spArr = [
        [[0], [1 - 0 - n], [0], [0, 1], [1], [0]],
        [[0], [2 - 0 - n], [1], [0, 1], [2], [0]],
        [[0], [2 - 1 - n], [2], [0, 1, 2], [3], [0]],
        [[0], [3 - 0 - n], [3], [0, 1], [3], [0]],
        [[0], [3 - 1 - n], [4], [0, 1, 2], [4], [0]],
        [[0], [3 - 2 - n], [5], [0, 1, 2], [5], [0]],
        [[0], [4 - 0 - n], [6], [0, 1], [4], [0]],
        [[0], [4 - 1 - n], [7], [0, 1, 2], [5], [0]],
        [[0], [4 - 2 - n], [8], [0, 1, 2], [6], [0]],
        [[0], [5 - 0 - n], [9], [0, 1], [5], [0]],
        [[0], [5 - 1 - n], [10], [0, 1, 2], [6], [0]],
        [[0], [5 - 2 - n], [11], [0, 1, 2], [7], [0]],
        [[0], zsArr, [12], [0, 1, 2], [6, 7], [0]],
        [[1], [0 - 0 - n], [13], [4], [0], [0]],
        [[1], [1 - 1 - n], [14], [3, 4, 5], [2], [0]],
        [[1], [2 - 2 - n], [15], [3, 4, 5], [4], [0]],
        [[1], [3 - 3 - n], [16], [3, 4, 5], [6], [0]],
        [[1], [-1 * n], [17], [3, 4, 5], [7], [0]],
        [[2], [0 - 1 - n], [18], [7, 8], [1], [1]],
        [[2], [0 - 2 - n], [19], [7, 8], [2], [1]],
        [[2], [1 - 2 - n], [20], [6, 7, 8], [3], [1]],
        [[2], [0 - 3 - n], [21], [7, 8], [3], [1]],
        [[2], [1 - 3 - n], [22], [6, 7, 8], [4], [1]],
        [[2], [2 - 3 - n], [23], [6, 7, 8], [5], [1]],
        [[2], [0 - 4 - n], [24], [7, 8], [4], [1]],
        [[2], [1 - 4 - n], [25], [6, 7, 8], [5], [1]],
        [[2], [2 - 4 - n], [26], [6, 7, 8], [6], [1]],
        [[2], [0 - 5 - n], [27], [7, 8], [5], [1]],
        [[2], [1 - 5 - n], [28], [6, 7, 8], [6], [1]],
        [[2], [2 - 5 - n], [29], [6, 7, 8], [7], [1]],
        [[2], zfArr, [30], [6, 7, 8], [6, 7], [1]]
    ];
    return spArr;
}

class Football {
    constructor(chuan, choose, matchChoose, multiNum = 1) {
        this.chuan = chuan;
        this.selChuanArr = this.getSelChuanArrByChuan(chuan);
        this.choose = choose;
        this.choose_len = Object.keys(choose).length;
        this.matchChoose = matchChoose;
        this.multiNum = multiNum;
        this.dans = [];
    }
    getSelChuanArrByChuan(chuan) {
        // 计算 串1最小过关数
        const cn = chuan.filter(item => item.split('_')[1] === '1')
        let cnMin = 0
        if (cn.length) {
            const cnsort = cn.sort((a, b) => Number(a.split('_')[0]) - Number(b.split('_')[0]))
            cnMin = Number(cnsort[0].split('_')[0])
        }
        // 计算 串M最小过关数
        const cm = chuan.filter(item => item.split('_')[1] !== '1')
        let cmMin = 0
        if (cm.length) {
            const cmsort = cm.map(item => GetVotetype(item).split(' ')).flat().sort()
            cmMin = Number(cmsort[0])
        }
        // 计算 所有串关中的最小过关数
        let cMin = 0
        if (cnMin === 0 || cmMin === 0) {
            cMin = Math.max(cnMin, cmMin)
        } else {
            cMin = Math.min(cnMin, cmMin)
        }
        // cMin 所有串关方式中的最小值,  cmMin M串N的最小值 不选多串默认0
        return [cMin, cmMin]
    }
    updateMult(multiNum){ // 更改倍数
        this.multiNum = multiNum;
        // 重新返回当前最高奖金
        return this.getMaxBonus();
    }
    updateChuan(chuan) { // 更新串关方式
        this.chuan = chuan;
        this.selChuanArr = this.getSelChuanArrByChuan(chuan);
    }
    updateChoose(chuan, choose, matchChoose) { // 更新选中的比赛
        this.chuan = chuan;
        this.selChuanArr = this.getSelChuanArrByChuan(chuan);
        this.choose = choose;
        this.choose_len = Object.keys(choose).length;
        this.matchChoose = matchChoose;
    }
    setDan(dans){
        this.dans = dans;
    }
    // 获取总注数
    getZhuShu(){
        let sa = [], sb = [] // sb 胆码数组
        for (const mod in this.choose) {
            let tp = []
            let n = {0: 0,1: 0,2: 0,3: 0,4: 0}
            // 增加记录具体的玩法
            let nwf = {0: '',1: '',2: '',3: '',4: ''}
            for (const wf in this.choose[mod]) {
                const _vals = Object.values(this.choose[mod][wf])
                n[wf] = _vals.length
                nwf[wf] = _vals.map(v => `${v.xx}@${v.sp}`).join(',')
            }
            for (const wf in n) {
                if (n[wf]) {
                    tp.push(`${wfconf[wf]}-${n[wf]}-${nwf[wf]}=${mod}`)
                }
            }
            if (this.dans.includes(mod)) {
                sb.push(tp)
            } else {
                sa.push(tp)
            }
        }
        let zhushu = 0
        for (const ggWay of this.chuan){ // 循环串关
            zhushu += myCalc(ggWay, sa, sb)
        }
        return zhushu;
    }
    // 最高奖金
    getMaxBonus(){
        if (this.dans.length>0){
            return getDanMinMaxPrize(this.chuan, this.selChuanArr, this.matchChoose, this.choose, this.choose_len, this.multiNum, this.dans, true)
        }else{
            return getMinMaxPrize1(this.chuan, this.selChuanArr, this.matchChoose, this.choose, this.choose_len, this.multiNum, true)
        }
    }
    // 奖金评测
    bonusTest() {
        return getMinMaxPrize1(this.chuan, this.selChuanArr, this.matchChoose, this.choose, this.choose_len, this.multiNum)
    }

    // 定胆评测
    danTest(){
        return getDanMinMaxPrize(this.chuan, this.selChuanArr, this.matchChoose, this.choose, this.choose_len, this.multiNum, this.dans)
    }

    // 奖金优化
    bonusOpt(orderData) {
        return optNeedData(orderData, this.chuan)
    }

    destroy() {
        // 清除所有内部引用（如果有的话）
    }
}

export {
    Football,
    countMaxOdds,
    optNeedData,
}
